﻿using System;
using System.Collections.Generic;
using System.Data;
using System.Globalization;
using System.IO;
using System.Windows;
using System.Windows.Data;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using CAION2.Classes;
using CAION2.Models;
using CAION2.Properties;


namespace CAION2.ViewModels
{
    using System.Linq;

    using FirstFloor.ModernUI.Presentation;

    public class ItemTypeColorConverter : IValueConverter
    {
        public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
        {
            SolidColorBrush commonColor = new SolidColorBrush(Color.FromArgb(255, 171, 169, 169));
            
            if (DBNull.Value.Equals(value)) return commonColor;
            if (value == null) return commonColor;

            SolidColorBrush result;

            switch (value.ToString().ToLower())
            {
                //case "common":
                //    return commonColor;
                case "rare":
                    result = new SolidColorBrush(Color.FromArgb(255, 41, 169, 32));
                    break;
                case "legend":
                    result = new SolidColorBrush(Color.FromArgb(255, 24, 154, 223));
                    break;
                case "unique":
                    result = new SolidColorBrush(Color.FromArgb(255, 235, 189, 4));
                    break;
                case "epic":
                    result = new SolidColorBrush(Color.FromArgb(255, 251, 121, 14));
                    break;
                case "mythic":
                    result = new SolidColorBrush(Color.FromArgb(255, 113, 10, 241));
                    break;
                default:
                    result = commonColor;
                    break;
            }

            if ((string) parameter == "TextColor")
            {
                return "#" + result.Color.R.ToString("X2") + result.Color.G.ToString("X2") + result.Color.B.ToString("X2"); 
            }

            return result;
        }

        public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
        {
            return null;
        }

    }

    public class IdianRandomTextConverter : IValueConverter
    {
        public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
        {
            KeyValuePair<string, Single> stat = (KeyValuePair<string, Single>)value;
            if (string.IsNullOrEmpty(stat.Key)) return "";

            string translate = CardStat.GetStatTranslate(stat.Key);

            string sign = "";
            if (stat.Value > 0) sign = "+";

            return parameter as string == "AccentColor" 
                ? string.Format("{0} [color=" + AppearanceManager.Current.AccentColor + "]{2}{1}[/color]", translate, stat.Value, sign) 
                : string.Format("{0} [b]{2}{1}[/b]", translate, stat.Value, sign);
        }

        public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
        {
            return null;
        }

    }

    public class CharacterTextConverter : IValueConverter
    {
        public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
        {
            KeyValuePair<string, Single> stat = (KeyValuePair<string, Single>)value;
            
            if (string.IsNullOrEmpty(stat.Key)) return "";
            
            string translate = CardStat.GetStatTranslate(stat.Key);
            
            char sign = ' ';
            if (parameter != null) sign = System.Convert.ToChar(parameter);

            string result = string.Format("{0,-20}[color=" + AppearanceManager.Current.AccentColor +"]{2}{1}[/color]", translate, stat.Value, sign);
            return result;
        }

        public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
        {
            return null;
        }

    }

    public class BonusTextConverter : IValueConverter
    {
        public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
        {
            KeyValuePair<string, Single> stat = (KeyValuePair<string, Single>)value;
            if (string.IsNullOrEmpty(stat.Key)) return "";

            string preSign = "+";
            if (stat.Value < 0) preSign = "";
            string postSign = "";
            if (parameter != null)
            {
                string[] signs = parameter as string[];
                if (signs != null && signs.Any()) preSign = signs[0];
                if (signs != null && signs.Count() > 1) postSign = signs[1];
            }
            
            string result = string.Format("{0,-20}[color=" + AppearanceManager.Current.AccentColor + "]{2}{1}{3}[/color]", stat.Key, stat.Value, preSign, postSign);
            return result;
        }

        public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
        {
            return null;
        }

    }

    public class ItemSetTextConverter : IValueConverter
    {
        public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
        {
            KeyValuePair<string, Single> stat = (KeyValuePair<string, Single>)value;
            if (string.IsNullOrEmpty(stat.Key)) return "";

            string preSign = "+";
            if (stat.Value < 0) preSign = "";
            
            string translate = CardStat.GetStatTranslate(stat.Key);
            string result = "";
            if ((bool)parameter)
            {
                result = string.Format("{0,-20}[color=" + AppearanceManager.Current.AccentColor + "]{2}{1}[/color]", translate, stat.Value, preSign);
            }
            else
            {
                result = string.Format("{0,-20}{2}{1}", translate, stat.Value, preSign);
            }
            
            return result;
        }

        public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
        {
            return null;
        }

    }
    
    public class GameClassIconConverter : IValueConverter
    {
        public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
        {
            string className = value.ToString();

            if (className == Resources.Class_Knight)
            {
                return new BitmapImage(new Uri("/CAION2;component/UI2/Emblems/icon_emblem_knight.png", UriKind.RelativeOrAbsolute));
            }
            if (className == Resources.Class_Fighter)
            {
                return new BitmapImage(new Uri("/CAION2;component/UI2/Emblems/icon_emblem_fighter.png", UriKind.RelativeOrAbsolute));
            }
            if (className == Resources.Class_Assassin)
            {
                return new BitmapImage(new Uri("/CAION2;component/UI2/Emblems/icon_emblem_assassin.png", UriKind.RelativeOrAbsolute));
            }
            if (className == Resources.Class_Ranger)
            {
                return new BitmapImage(new Uri("/CAION2;component/UI2/Emblems/icon_emblem_ranger.png", UriKind.RelativeOrAbsolute));
            }
            if (className == Resources.Class_Elementalist)
            {
                return new BitmapImage(new Uri("/CAION2;component/UI2/Emblems/icon_emblem_elementalist.png", UriKind.RelativeOrAbsolute));
            }
            if (className == Resources.Class_Wizard)
            {
                return new BitmapImage(new Uri("/CAION2;component/UI2/Emblems/icon_emblem_wizard.png", UriKind.RelativeOrAbsolute));
            }
            if (className == Resources.Class_Chanter)
            {
                return new BitmapImage(new Uri("/CAION2;component/UI2/Emblems/icon_emblem_chanter.png", UriKind.RelativeOrAbsolute));
            }
            if (className == Resources.Class_Priest)
            {
                return new BitmapImage(new Uri("/CAION2;component/UI2/Emblems/icon_emblem_priest.png", UriKind.RelativeOrAbsolute));
            }
            if (className == Resources.Class_Bard)
            {
                return new BitmapImage(new Uri("/CAION2;component/UI2/Emblems/icon_emblem_bard.png", UriKind.RelativeOrAbsolute));
            }
            if (className == Resources.Class_Gunner)
            {
                return new BitmapImage(new Uri("/CAION2;component/UI2/Emblems/icon_emblem_gunner.png", UriKind.RelativeOrAbsolute));
            }
            if (className == Resources.Class_Rider)
            {
                return new BitmapImage(new Uri("/CAION2;component/UI2/Emblems/icon_emblem_Rider.png", UriKind.RelativeOrAbsolute));
            }

            return null;
        }

        public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
        {
            return null;
        }

    }

    public class IconConverter : IValueConverter
    {
        public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
        {
            if (string.IsNullOrEmpty(value as string)) return null;

            string iconName = value.ToString();
            if (iconName.Contains(".dds")) iconName = iconName.Remove(iconName.Length - 4);
            string imagePath = Path.Combine(DataModel.IconsDirectory, iconName.Trim() + ".png");

            return File.Exists(imagePath) ? new BitmapImage(new Uri(imagePath)) : null;
        }

        public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
        {
            throw new NotSupportedException("Ошибочка с картинками!");
        }
    }

    public class TextLenghtToVisibleConverter : IValueConverter
    {
        public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
        {
            if (value == null) return Visibility.Collapsed;

            return string.IsNullOrEmpty(value.ToString()) ? Visibility.Collapsed : Visibility.Visible;
        }

        public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
        {
            throw new NotSupportedException("Ошибочка!");
        }
    }

    public class StatsListToolTipConverter : IMultiValueConverter
    {
        public object Convert(object[] values, Type targetType, object parameter, CultureInfo culture)
        {
            string plus = "";
            if (values[1].ToString().First() != '+') plus = "+";
            return string.Format("{0} {2}{1}", values[0], values[1], plus);
        }

        public object[] ConvertBack(object value, Type[] targetTypes, object parameter, CultureInfo culture)
        {
            throw new NotSupportedException("Ошибочка!");
        }
    }

    [ValueConversion(typeof(bool), typeof(bool))]
    [ValueConversion(typeof(Visibility), typeof(Visibility))]
    public class InvertConverter : IValueConverter
    {
        public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
        {
            switch (targetType.Name)
            {
                case "Visibility":
                    Visibility visibilityValue = (Visibility)value;
                    return visibilityValue == Visibility.Visible ? Visibility.Collapsed : Visibility.Visible;
                case "Boolean":
                    bool booleanValue = (bool)value;
                    return !booleanValue;
            }

            if ((bool)value == false || (bool)value) return !(bool)value;

            return null;
        }

        public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
        {
            bool booleanValue = (bool)value;
            return !booleanValue;
        }
    }

    public class StigmaToolTipConverter : IValueConverter
    {
        public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
        {
            switch (parameter.ToString())
            {
                case "Extra":
                    //return FillExtraInfo(value, 11, 12, 10, 25, 26);
                case "Enhanted":
                    return FillExtraInfo(value, 28, 29, 27, 42, 43);
                case "Level":
                    return string.Format(Resources.Stigma_Level, value);
                default:
                    return "";
            }
        }

        private string FillExtraInfo(object value, int iCost, int iCost2, int iUnit, int iCasttime, int iCooldown)
        {
            object[] row = (object[])value;
            string result = "";

            int cost = 0;
            if (row[iCost] != DBNull.Value) cost = System.Convert.ToInt32(row[iCost]);
            if (row[iCost2] != DBNull.Value) cost += System.Convert.ToInt32(row[iCost2]);

            string unit = row[iUnit].ToString();

            switch (unit.ToUpper())
            {
                case "MP_RATIO":
                    unit = "% MP";
                    break;
                case "HP_RATIO":
                    unit = "% HP";
                    break;
                default:
                    unit = " " + unit;
                    break;
            }

            int costTime = 0;
            if (row[49] != DBNull.Value) costTime = System.Convert.ToInt32(row[49]);
            if (costTime > 0)
            {
                costTime = costTime/1000;
                unit = string.Format("{0} {1} {2} {3}", unit, Resources.Stigma_CostTime, costTime, Resources.Time_Sec);
            }

            if (cost > 0) result = string.Format(Resources.Stigma_SkillCost, cost, unit);

            float casttime = 0;
            if (row[iCasttime] != DBNull.Value) casttime = System.Convert.ToSingle(row[iCasttime]) / 1000;
            if (casttime > 0)
            {
                result += "\n" + string.Format(Resources.Stigma_CastTime, casttime, Resources.Time_Sec);
            }
            else
            {
                result += "\n" + string.Format(Resources.Stigma_CastTime, Resources.Stigma_CastTimeInstantly, "");
            }

            float cooldown = 0;
            if (row[iCooldown] != DBNull.Value) cooldown = System.Convert.ToSingle(row[iCooldown]) / 1000;
            if (cooldown > 0)
            {
                if (cooldown > 59)
                {
                    cooldown = cooldown / 60;
                    result += "\n" + string.Format(Resources.Stigma_CoolDown, cooldown, Resources.Time_Min);
                }
                else
                {
                    result += "\n" + string.Format(Resources.Stigma_CoolDown, cooldown, Resources.Time_Sec);
                }
            }

            return result;
        }
        
        public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
        {
            throw new NotSupportedException("Ошибочка!");
        }
    }

    public class StigmaToolTipCreatorConverter : IValueConverter
    {
        public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
        {
            if (value == null) return new StigmaToolTipViewModel(null, null);

            string condition = string.Format("name = '{0}'", value);
            string fields = "name, translate" + DataModel.EngFix + " AS translate, desc_long" + DataModel.EngFix + " AS desc_long, "
                            + "skillicon_name, level, quality, require_shard, skill_group_name, "
                            + "warrior, scout, mage, cleric, engineer, artist, fighter, knight, assassin, ranger, wizard, elementalist, chanter, priest, gunner, bard, rider, "
                            + "abyss_point, charge_set_name, cost_parameter, cost_end, cost_end_lv, required_sword, required_mace, "
                            + "required_dagger, required_2hsword, required_polearm, required_staff, required_bow, required_orb, required_book, "
                            + "required_gun, required_cannon, required_harp, casting_delay, delay_time, first_target, require_skill1, "
                            + "require_skill2, instant_skill, race_permitted, cost_time";

            DataRow row = DataModel.GetRow("Stigmas", condition, fields, 1);

            return new StigmaToolTipViewModel(null, row);
        }

        public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
        {
            throw new NotSupportedException("Ошибочка!");
        }
    }

    public class BooleanToBitConverter : IValueConverter
    {
        public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
        {
            if (!(value is bool)) return "1";
            if ((bool) value) return "1";
            return "0";
        }

        public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
        {
            throw new NotSupportedException("Ошибочка!");
        }
    }

    }
